package com.jmb.api.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jmb.api.common.exception.ValidUtilException;
import com.jmb.api.common.utils.JsonUtil;
import com.jmb.api.common.utils.ValidUtil;
import com.jmb.api.entity.InterfaceAssert;
import com.jmb.api.web.mapper.InterfaceCaseMapper;
import com.jmb.api.web.service.InterfaceAssertService;
import com.jmb.api.web.mapper.InterfaceAssertMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.jar.JarException;

/**
* @author jin
* @description 针对表【t_interface_assert】的数据库操作Service实现
* @createDate 2025-09-25 17:13:12
*/
@Slf4j
@Service
public class InterfaceAssertServiceImpl extends ServiceImpl<InterfaceAssertMapper, InterfaceAssert>
    implements InterfaceAssertService{
    @Autowired
    private InterfaceCaseMapper interfaceCaseMapper;

    /**
     * 保存更新断言
     * @param interfaceAssert 断言
     */
    @Override
    public void saveAssert(InterfaceAssert interfaceAssert) {
        checkDO(interfaceAssert);
        boolean isUpdate = interfaceAssert.getId() == null;
        Long caseId = interfaceAssert.getCaseId();
        // 判断用例编号是否存在相同Order
        InterfaceAssert anAssert = new InterfaceAssert();
        anAssert.setOrder(interfaceAssert.getOrder());
        anAssert.setCaseId(interfaceAssert.getCaseId());
        // 判断用例编号是否存在
        if (interfaceCaseMapper.selectInterfaceCaseByCaseId(caseId)==null){
            log.warn("新增断言用例编号不存在 {} ", caseId);
        }
        LambdaQueryWrapper<InterfaceAssert> assertLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 判断是否修改操作，需要排除当前校色本身
        if (isUpdate){
            assertLambdaQueryWrapper.ne(InterfaceAssert::getId, interfaceAssert.getId());
        }
        super.saveOrUpdate(interfaceAssert);

    }

    /**
     * 检查接口断言数据对象的有效性
     * @param interfaceAssertDO 接口断言数据对象
     * @throws ValidUtilException 当数据不符合验证规则时抛出异常
     */
    public void checkDO(InterfaceAssert interfaceAssertDO) throws ValidUtilException {
        Long caseId = interfaceAssertDO.getCaseId();
        ValidUtil.notNUll(caseId, "用例编号不能为空");

        String assertName = interfaceAssertDO.getAssertName();
        ValidUtil.notNUll(assertName, "断言名称不能为空");
        ValidUtil.notEmpty(assertName, "断言名称不能为空");
        ValidUtil.length(assertName, 100, "断言名称长度必须小于100");

        Integer type = interfaceAssertDO.getType();
        ValidUtil.notNUll(type, "提取数据类型不能为空");
        ValidUtil.size(type, 0, 4,"提取数据类型必须为0~4");

        String expression = interfaceAssertDO.getExpression();
        // 验证提取表达式（仅适用于类型0、1、2）
        if (type < 3) { // 提取数据类型   0json/1html/2header/3responseCode/4runtime
            ValidUtil.notNUll(expression, "提取表达式不能为空");
            ValidUtil.notEmpty(expression, "提取表达式不能为空");
            ValidUtil.length(expression, 50, "提取表达式长度必须小于50");
        }

        Integer operator = interfaceAssertDO.getOperator();
        ValidUtil.notNUll(operator, "操作符不能为空");
        ValidUtil.size(operator, 0, 12,"操作符必须为0~12");

        String exceptedResult = interfaceAssertDO.getExceptedResult();
        // 验证预期结果（除特定操作符外都需要填写）
        if (operator != 8 && operator != 9 && operator != 11 && operator != 12) {
            ValidUtil.notNUll(exceptedResult, "预期结果不能为空");
            ValidUtil.notEmpty(exceptedResult, "预期结果不能为空");
        }
        ValidUtil.length(exceptedResult, 0, 1000,"预期结果长度必须小于1000");

        Integer order = interfaceAssertDO.getOrder();
        ValidUtil.notNUll(order, "排序不能为空");

        // 根据不同类型验证表达式格式
        // 检查 0json/1html/2header/3responsecode
        if (type == 0) {
            JsonUtil.isJsonPath(expression);
        } else if (type == 1) {
            JsonUtil.isXpath(expression);
        } else if (type == 3) {
            try {
                Integer.valueOf(exceptedResult);
            } catch (NumberFormatException e) {
                throw new ValidUtilException("响应状态码预期结果错误");
            }
        }
    }
}




